import os

import jmespath

from config_params.base_util import baseUtil
from jmeter_api.basics.thread_group.bzm_elements import Unit
from jmeter_api.basics.thread_group.elements import ThreadGroupAction


class Threads:

    def __init__(self, data):
        self.data = data

    def jme_path(self, exp):
        return jmespath.search(exp, self.data)

    def test_plan(self):
        version = self.jme_path("version")
        properties = self.jme_path("properties")
        jmeter = self.jme_path("jmeter")
        os.environ["version"] = str(version)
        os.environ["properties"] = str(properties)
        os.environ["jmeter"] = str(jmeter)
        if self.jme_path("testPlan") is not None:
            variables = self.jme_path("testPlan.variables")
            var_dict = {}
            if variables is not None:
                for k, v in variables.items():
                    var_dict[k] = str(v)
            else:
                var_dict = {}
            plan_params = {
                "name": self.jme_path("testPlan.name") if self.jme_path("testPlan.name") is not None else "",
                "variables": var_dict,
                "comments": self.jme_path("testPlan.comments") if self.jme_path(
                    "testPlan.comments") is not None else "",
                "is_enabled": self.jme_path("testPlan.is_enabled") if self.jme_path(
                    "testPlan.is_enabled") is not None else True,
                "functional_mode": self.jme_path("testPlan.functional_mode") if self.jme_path(
                    "testPlan.functional_mode") is not None else False,
                "teardown_on_shutdown": self.jme_path("testPlan.teardown_on_shutdown") if self.jme_path(
                    "testPlan.teardown_on_shutdown") is not None else True,
                "serialize_threadgroups": self.jme_path("testPlan.serialize_threadgroups") if self.jme_path(
                    "testPlan.serialize_threadgroups") is not None else False
            }
            test_plan = baseUtil.create_instance(self.jme_path("testPlan.type"), plan_params)
            return test_plan

    def CommonThreadGroup(self, thread_obj):
        thread_group_dict = {}
        thread_group_dict["name"] = self.jme_path("name") if self.jme_path("name") is not None else "Thread Group"
        thread_group_dict["comments"] = self.jme_path("comments") if self.jme_path("comments") is not None else ""
        thread_group_dict["num_threads"] = self.jme_path("num_threads") if self.jme_path("num_threads") is not None else 1
        thread_group_dict["ramp_time"] = self.jme_path("ramp_time") if self.jme_path("ramp_time") is not None else 0
        thread_group_dict["continue_forever"] = self.jme_path("continue_forever") if self.jme_path("continue_forever") is not None else False
        thread_group_dict["loops"] = self.jme_path("loops") if self.jme_path("loops") is not None else None
        thread_group_dict["delayed_start"] = self.jme_path("delayed_start") if self.jme_path("delayed_start") is not None else False
        thread_group_dict["is_sheduler_enable"] = self.jme_path("is_sheduler_enable") if self.jme_path("is_sheduler_enable") is not None else False
        thread_group_dict["sheduler_duration"] = self.jme_path("sheduler_duration") if self.jme_path("sheduler_duration") is not None else None
        thread_group_dict["sheduler_delay"] = self.jme_path("sheduler_delay") if self.jme_path("sheduler_delay") is not None else None
        thread_group_dict["is_enabled"] = self.jme_path("is_enabled") if self.jme_path("is_enabled") is not None else True
        on_sample_error = self.jme_path("on_sample_error")
        threadGroupAction = baseUtil.get_instance_attr("ThreadGroupAction")
        if on_sample_error == "continue":
            thread_group_dict["on_sample_error"] = threadGroupAction.CONTINUE
        elif on_sample_error == "startnextloop":
            thread_group_dict["on_sample_error"] = threadGroupAction.START_NEXT_LOOP
        elif on_sample_error == "stopthread":
            thread_group_dict["on_sample_error"] = threadGroupAction.STOP_THREAD
        elif on_sample_error == "stoptest":
            thread_group_dict["on_sample_error"] = threadGroupAction.STOP_TEST
        elif on_sample_error == "stoptestnow":
            thread_group_dict["on_sample_error"] = threadGroupAction.STOP_TEST_NOW
        else:
            thread_group_dict["on_sample_error"] = threadGroupAction.CONTINUE
        thread_group_obj = baseUtil.create_instance(thread_obj, thread_group_dict)
        return thread_group_obj
    def ConcurrencyThreadGroup(self, thread_obj):
        concurrency_threadGroup_dict = {}
        concurrency_threadGroup_dict["name"] = self.jme_path("name") if self.jme_path("name") is not None else "bzm - Concurrency Thread Group"
        concurrency_threadGroup_dict["comments"] = self.jme_path("comments") if self.jme_path("comments") is not None else ""
        concurrency_threadGroup_dict["target_concurrency"] = self.jme_path("target_concurrency") if self.jme_path("target_concurrency") is not None else 0
        concurrency_threadGroup_dict["ramp_up"] = self.jme_path("ramp_up") if self.jme_path("ramp_up") is not None else 1
        concurrency_threadGroup_dict["steps"] = self.jme_path("steps") if self.jme_path("steps") is not None else 1
        concurrency_threadGroup_dict["hold"] = self.jme_path("hold") if self.jme_path("hold") is not None else 0
        concurrency_threadGroup_dict["iterations"] = self.jme_path("iterations") if self.jme_path("iterations") is not None else None

        unit = self.jme_path("unit")
        if unit == "M":
            concurrency_threadGroup_dict["unit"] = Unit.MINUTE
        if unit == "S":
            concurrency_threadGroup_dict["unit"] = Unit.SECOND
        on_sample_error = self.jme_path("on_sample_error")
        if on_sample_error == "continue":
            concurrency_threadGroup_dict["on_sample_error"] = ThreadGroupAction.CONTINUE
        elif on_sample_error == "startnextloop":
            concurrency_threadGroup_dict["on_sample_error"] = ThreadGroupAction.START_NEXT_LOOP
        elif on_sample_error == "stopthread":
            concurrency_threadGroup_dict["on_sample_error"] = ThreadGroupAction.STOP_THREAD
        elif on_sample_error == "stoptest":
            concurrency_threadGroup_dict["on_sample_error"] = ThreadGroupAction.STOP_TEST
        elif on_sample_error == "stoptestnow":
            concurrency_threadGroup_dict["on_sample_error"] = ThreadGroupAction.STOP_TEST_NOW
        concurrency_threadGroup_dict["is_enabled"] = self.jme_path("is_enabled") if self.jme_path("is_enabled") is not None else True

        thread_group_obj = baseUtil.create_instance(thread_obj, concurrency_threadGroup_dict)
        return thread_group_obj

    def threads(self):
        thread_obj = self.jme_path("type")
        thread_obj_list = []
        if thread_obj == "CommonThreadGroup":
            thread_group_obj = self.CommonThreadGroup(thread_obj)
            thread_obj_list.append(thread_group_obj)
        if thread_obj == "ConcurrencyThreadGroup":
            ConcurrencyThreadGroup = self.ConcurrencyThreadGroup(thread_obj)
            thread_obj_list.append(ConcurrencyThreadGroup)
        return thread_obj_list
